﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Windows.Navigation;
using System.IO.IsolatedStorage;
using System.IO;
using System.Text;
using System.Windows.Media.Imaging;
using System.Windows.Controls.Primitives;
using Microsoft.Phone.Net.NetworkInformation;
using System.Windows.Threading;
using System.Device.Location;

namespace NearChat
{
    public partial class Chat : PhoneApplicationPage
    {
        //storage dell'applicazione
        private static IsolatedStorageSettings appSettings = IsolatedStorageSettings.ApplicationSettings;

        //timer refresh
        private DispatcherTimer myDispatcherTimer;

        private string user;
        private string IDuser;

        private bool reload = true;

        //dati utente 2
        private string IDuser2;
        private string nameUser2;
        private string imageUser2;
        private string latUser2;
        private string lonUser2;
        private string statoStellaUser2;
        private string statoDivietoUser2;

        private string postUpdate = "";
        private string frase = "";

        private bool forceGoBack=false;

        Style CanvasStyle = Application.Current.Resources["ListaPreferiti"] as Style;
        Style CanvasBorderStyle = Application.Current.Resources["BorderCanvas"] as Style;
        Style ImageBorderStyle = Application.Current.Resources["ImgProfilo"] as Style;
        Style TextBlockStyle = Application.Current.Resources["Name"] as Style;
        Style PreferitiStyle = Application.Current.Resources["Preferiti"] as Style;
        Style BlackListStyle = Application.Current.Resources["BlackList"] as Style;
        Style ProfileStyle = Application.Current.Resources["Profile"] as Style;

        Style MyTextStyle = Application.Current.Resources["myTextBorder"] as Style;
        Style YourTextStyle = Application.Current.Resources["yourTextBorder"] as Style;
        Style ChatTextStyle = Application.Current.Resources["MessageText"] as Style;

        public Chat()
        {
            InitializeComponent();

            //salvo i dati in locale
            IDuser = appSettings["ID"].ToString();
            user = appSettings["user"].ToString();

            buttonSend.IsEnabled = false;//bottone invia disabilitato
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
            string idOUT = string.Empty;
            if (NavigationContext.QueryString.TryGetValue("ID", out idOUT))
                IDuser2 = idOUT;
        }//OnNavigatedTo

        private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
        {
            //creazione e settaggio timer
            myDispatcherTimer = new System.Windows.Threading.DispatcherTimer();
            myDispatcherTimer.Interval = new TimeSpan(0, 0, 10);//ongi 10 secondi
            myDispatcherTimer.Tick += new EventHandler(Each_Tick);
            myDispatcherTimer.Start();
        }//PhoneApplicationPage_Loaded

        void GetRequestStreamCallbackDati(IAsyncResult callbackResult)
        {
            HttpWebRequest myRequest = (HttpWebRequest)callbackResult.AsyncState;
            // End the stream request operation
            Stream postStream = myRequest.EndGetRequestStream(callbackResult);

            // Create the post data
            string postData = "apikey=4nn!eSupp0rt&ID="+IDuser2;
            byte[] byteArray = Encoding.UTF8.GetBytes(postData);

            // Add the post data to the web request
            postStream.Write(byteArray, 0, byteArray.Length);
            postStream.Close();

            // Start the web request
            myRequest.BeginGetResponse(new AsyncCallback(GetResponsetStreamCallbackDati), myRequest);
        }//GetRequestStreamCallbackDati

        void GetResponsetStreamCallbackDati(IAsyncResult callbackResult)
        {
            HttpWebRequest request = (HttpWebRequest)callbackResult.AsyncState;
            HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult);
            using (StreamReader httpWebStreamReader = new StreamReader(response.GetResponseStream()))
            {
                string result = httpWebStreamReader.ReadToEnd();
                Dispatcher.BeginInvoke(() => ParsingDati(result));
            }
        }//GetResponsetStreamCallbackDati

        void ParsingDati(string result)
        {
            if (result != "")
            {
                string[] ris = majorSplit(result); 
                ris = minorSplit(ris[0]);//sono sicuro che rappresenta un solo record

                if (ris[0] == "ERRORE")
                {
                    MessageBox.Show(ris[1]);
                }
                else
                {
                    listUtente.Items.Clear();

                    //estrapolo i dati
                    IDuser2 = ris[0];
                    nameUser2=ris[1];
                    imageUser2 = ris[2];
                    latUser2 = ris[3];
                    lonUser2 = ris[4];
                    statoStellaUser2 = ris[5]; 
                    statoDivietoUser2 = ris[6]; 

                    //inserisco nel canvas
                    Canvas CanvasUtente= new Canvas();
                    CanvasUtente.Style = CanvasStyle;

                    Border CanvasBorder = new Border();
                    CanvasBorder.Style = CanvasBorderStyle;

                    Border CanvasImage = new Border();
                    CanvasImage.Style = ImageBorderStyle;
                    CanvasImage.Tag = imageUser2;
                    CanvasImage.Loaded += new RoutedEventHandler(CanvasImage_Loaded);

                    TextBlock CanvasUsername = new TextBlock();
                    CanvasUsername.Style = TextBlockStyle;
                    CanvasUsername.Text = nameUser2;
                    
                    ToggleButton CanvasStella = new ToggleButton();
                    CanvasStella.Style = PreferitiStyle;
                    CanvasStella.IsChecked = (statoStellaUser2 != ""); 
                    CanvasStella.Tap += new EventHandler<GestureEventArgs>(CanvasStella_Tap);
                    CanvasStella.Checked += new RoutedEventHandler(CanvasStella_Checked);
                    CanvasStella.Unchecked += new RoutedEventHandler(CanvasStella_Unchecked);
                    CanvasStella.Loaded += new RoutedEventHandler(CanvasStella_Loaded);
                    CanvasStella.Tag = IDuser2;

                    ToggleButton CanvasDivieto = new ToggleButton();
                    CanvasDivieto.Style = BlackListStyle;
                    CanvasDivieto.IsChecked = (statoDivietoUser2 != ""); 
                    CanvasDivieto.Tap += new EventHandler<GestureEventArgs>(CanvasDivieto_Tap);
                    CanvasDivieto.Checked += new RoutedEventHandler(CanvasDivieto_Checked);
                    CanvasDivieto.Unchecked += new RoutedEventHandler(CanvasDivieto_Unchecked);
                    CanvasDivieto.Loaded += new RoutedEventHandler(CanvasDivieto_Loaded);
                    CanvasDivieto.Tag = IDuser2;

                    Button CanvasProfilo = new Button();
                    CanvasProfilo.Style = ProfileStyle;
                    CanvasProfilo.Click += new RoutedEventHandler(CanvasProfilo_Click);
                    CanvasProfilo.Loaded += new RoutedEventHandler(CanvasProfilo_Loaded);
                    CanvasProfilo.Tag = IDuser2;
                
                    CanvasUtente.Children.Add(CanvasImage);
                    CanvasUtente.Children.Add(CanvasUsername);
                    CanvasUtente.Children.Add(CanvasBorder);
                    CanvasUtente.Children.Add(CanvasStella);
                    CanvasUtente.Children.Add(CanvasDivieto);
                    CanvasUtente.Children.Add(CanvasProfilo);
                
                    //aggiungo alla lista
                    listUtente.Items.Add(CanvasUtente);

                    //controllo del range
                    if (appSettings.Contains("lat"))//mi sono geolocalizzato
                    { 
                        double mylat = double.Parse(appSettings["lat"].ToString().Replace('.',','));
                        double mylon = double.Parse(appSettings["lon"].ToString().Replace('.', ','));

                        double yourlat = double.Parse(latUser2.Replace('.', ','));
                        double yourlon = double.Parse(lonUser2.Replace('.', ','));
                        
                        //sono in range e l'utente non è in blacklist
                        if (((yourlat < (mylat + 0.002) && yourlat > (mylat - 0.002)) && (yourlon < (mylon + 0.002) && yourlon > (mylon - 0.002))))//&&(statoDivietoUser2==""))
                            buttonSend.IsEnabled = true;//abilito il bottone
                        else
                            buttonSend.IsEnabled = false;//disabilito il bottone
                        
                    }
                    else//non ho dati di localizzazione? ERRORE
                        buttonSend.IsEnabled = false;//disabilito il bottone 
                    
                }
            }
            
        }//ParsingDati

        //splitta la stringa passata in base a |
        private string[] minorSplit(string result)
        {
            return result.Split('|');
        }

        //splitta la stringa passata in base a §
        private string[] majorSplit(string result)
        {
            return result.Split('§');
        }

        private void CanvasImage_Loaded(object sender, RoutedEventArgs e)
        {
            Border b = sender as Border;
            string url = b.Tag.ToString();
            BitmapImage urlProfilo = new BitmapImage(new Uri(url, UriKind.Absolute));

            ImageBrush sfondo = new ImageBrush();
            ImageSource src = urlProfilo;
            sfondo.ImageSource = src;
            b.Background = sfondo;
        }

        private void CanvasProfilo_Loaded(object sender, RoutedEventArgs e)
        {
            Button b = sender as Button;
            BitmapImage Profilo = new BitmapImage(new Uri("img/List.png", UriKind.Relative));

            ImageBrush sfondo = new ImageBrush();
            ImageSource src = Profilo;
            sfondo.ImageSource = src;
            b.Background = sfondo;
        }

        private void CanvasProfilo_Click(object sender, RoutedEventArgs e)
        {
            Button b = sender as Button;
            string TagOUT = (string)b.Tag;

            NavigationService.Navigate(new Uri("/Profilo.xaml?ID=" + TagOUT, UriKind.Relative));//cambio della pagina
        }

        private void CanvasStella_Loaded(object sender, RoutedEventArgs e)
        {
            ToggleButton tb = sender as ToggleButton;
            BitmapImage Stella=new BitmapImage();

            if ((bool)tb.IsChecked)
                Stella = new BitmapImage(new Uri("img/starUp.png", UriKind.Relative));

            else
                Stella = new BitmapImage(new Uri("img/starDown.png", UriKind.Relative));
                 
            ImageBrush sfondo = new ImageBrush();
            ImageSource src = Stella;
            sfondo.ImageSource = src;
            tb.Background = sfondo;
        }

        private void CanvasStella_Checked(object sender, RoutedEventArgs e)
        {
            ToggleButton tb = sender as ToggleButton;
            ImageBrush sfondo = new ImageBrush();
            BitmapImage StellaON = new BitmapImage(new Uri("img/starUp.png", UriKind.Relative));

            ImageSource src = StellaON;
            sfondo.ImageSource = src;
            tb.Background = sfondo;
        }

        private void CanvasStella_Unchecked(object sender, RoutedEventArgs e)
        {
            ToggleButton tb = sender as ToggleButton;
            ImageBrush sfondo = new ImageBrush();
            BitmapImage StellaOFF = new BitmapImage(new Uri("img/starDown.png", UriKind.Relative));

            ImageSource src = StellaOFF;
            sfondo.ImageSource = src;
            tb.Background = sfondo;
        }

        private void CanvasStella_Tap(object sender, GestureEventArgs e)
        {
            ToggleButton tb = sender as ToggleButton;
            string TagOUT = tb.Tag.ToString();

            if ((bool)tb.IsChecked)//l'ho appena attivato, devo renderlo preferito
            {
                postUpdate = "apikey=4nn!eSupp0rt&user1=" + IDuser + "&user2=" + TagOUT + "&favorite=1&blacklist=0";
                forceGoBack = false;
            }
            else //l'ho appena disattivato, lo tolgo dai preferiti
            {
                postUpdate = "apikey=4nn!eSupp0rt&user1=" + IDuser + "&user2=" + TagOUT + "&favorite=0&blacklist=0";
                forceGoBack = false;
            }

            if (NetworkInterface.GetIsNetworkAvailable())
            {
                //faccio request PHP al DB
                Uri myDBuri = new Uri("http://www.nearchat.altervista.org/updateState.php");
                HttpWebRequest stateRequest = (HttpWebRequest)HttpWebRequest.Create(myDBuri);
                stateRequest.Method = "POST";
                stateRequest.ContentType = "application/x-www-form-urlencoded";
                stateRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallbackState), stateRequest);
            }
            else
            {
                MessageBox.Show("connection error, please retry later.");
                //refresh
                RoutedEventArgs eve = new RoutedEventArgs();
                listUtente_Loaded(this, eve);
            }
        }

        private void CanvasDivieto_Loaded(object sender, RoutedEventArgs e)
        {
            ToggleButton tb = sender as ToggleButton;
            BitmapImage Divieto;

            if ((bool)tb.IsChecked)
                Divieto = new BitmapImage(new Uri("img/BlackListUp.png", UriKind.Relative));
            else
                Divieto = new BitmapImage(new Uri("img/BlackListDown.png", UriKind.Relative));

            ImageBrush sfondo = new ImageBrush();
            ImageSource src = Divieto;
            sfondo.ImageSource = src;
            tb.Background = sfondo;
        }

        private void CanvasDivieto_Checked(object sender, RoutedEventArgs e)
        {
            ToggleButton tb = sender as ToggleButton;
            ImageBrush sfondo = new ImageBrush();
            BitmapImage DivietoON = new BitmapImage(new Uri("img/BlackListUp.png", UriKind.Relative));

            ImageSource src = DivietoON;
            sfondo.ImageSource = src;
            tb.Background = sfondo;
        }

        private void CanvasDivieto_Unchecked(object sender, RoutedEventArgs e)
        {
            ToggleButton tb = sender as ToggleButton;
            ImageBrush sfondo = new ImageBrush();
            BitmapImage DivietoOFF = new BitmapImage(new Uri("img/BlackListDown.png", UriKind.Relative));

            ImageSource src = DivietoOFF;
            sfondo.ImageSource = src;
            tb.Background = sfondo;
        }

        private void CanvasDivieto_Tap(object sender, GestureEventArgs e)
        {
            ToggleButton tb = sender as ToggleButton;
            string TagOUT = tb.Tag.ToString();

            if ((bool)tb.IsChecked)//l'ho appena attivato, devo bloccarlo
            {
                postUpdate = "apikey=4nn!eSupp0rt&user1=" + IDuser + "&user2=" + TagOUT + "&favorite=0&blacklist=1";
                forceGoBack = true;//l'ho appena bloccato, non è consentito rispondere
            }
            else //l'ho appena disattivato, lo sblocco dalla blacklist
            {
                postUpdate = "apikey=4nn!eSupp0rt&user1=" + IDuser + "&user2=" + TagOUT + "&favorite=0&blacklist=0";
                forceGoBack = false;
            }

            if (NetworkInterface.GetIsNetworkAvailable())
            {
                //faccio request PHP al DB
                Uri myDBuri = new Uri("http://www.nearchat.altervista.org/updateState.php");
                HttpWebRequest stateRequest = (HttpWebRequest)HttpWebRequest.Create(myDBuri);
                stateRequest.Method = "POST";
                stateRequest.ContentType = "application/x-www-form-urlencoded";
                stateRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallbackState), stateRequest);
            }
            else
            {
                MessageBox.Show("connection error, please retry later.");
                //refresh
                RoutedEventArgs eve = new RoutedEventArgs();
                listUtente_Loaded(this, eve);
            }
        }

        private void buttonSend_Click(object sender, RoutedEventArgs e)
        {
            if (textBox.Text.ToString() != "")//se contiene qualcosa
            { 
                frase = textBox.Text.ToString();
                frase=frase.Replace('|','/');
                frase=frase.Replace('§','ç');
            
                Uri myDBuri1 = new Uri("http://www.nearchat.altervista.org/inviaMessaggio.php");
                HttpWebRequest sendRequest = (HttpWebRequest)HttpWebRequest.Create(myDBuri1);
                sendRequest.Method = "POST";
                sendRequest.ContentType = "application/x-www-form-urlencoded";
                sendRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallbackInvia), sendRequest);
            }   
        }//buttonSend_Click

        void GetRequestStreamCallbackInvia(IAsyncResult callbackResult)
        {
            HttpWebRequest myRequest = (HttpWebRequest)callbackResult.AsyncState;
            // End the stream request operation
            Stream postStream = myRequest.EndGetRequestStream(callbackResult);

            // Create the post data
            string postData = "apikey=4nn!eSupp0rt&user1=" + IDuser+"&user2="+IDuser2+"&text="+frase;
            byte[] byteArray = Encoding.UTF8.GetBytes(postData);

            // Add the post data to the web request
            postStream.Write(byteArray, 0, byteArray.Length);
            postStream.Close();

            // Start the web request
            myRequest.BeginGetResponse(new AsyncCallback(GetResponsetStreamCallbackInvia), myRequest);
        }//GetRequestStreamCallbackInvia

        void GetResponsetStreamCallbackInvia(IAsyncResult callbackResult)
        {
            HttpWebRequest request = (HttpWebRequest)callbackResult.AsyncState;
            HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult);
            using (StreamReader httpWebStreamReader = new StreamReader(response.GetResponseStream()))
            {
                string result = httpWebStreamReader.ReadToEnd();
                Dispatcher.BeginInvoke(() => ParsingInvia(result));
            }
        }//GetResponsetStreamCallbackInvia

        void ParsingInvia(string result)
        {
            frase = "";
            textBox.Text = "";

            if (result != "")//successo errore
            {
                string[] ris = majorSplit(result);
                ris = minorSplit(ris[0]);//sono sicuro che è uno solo

                if (ris[0] == "ERRORE")
                    MessageBox.Show(ris[1]);//stampo l'errore
            }
            else //non sono avvenuti errori
            {
                //refresh
                RoutedEventArgs eve = new RoutedEventArgs();
                listChat_Loaded(this,eve);
            }
        }//ParsingInvia

        void GetRequestStreamCallbackState(IAsyncResult callbackResult)
        {
            HttpWebRequest myRequest = (HttpWebRequest)callbackResult.AsyncState;
            // End the stream request operation
            Stream postStream = myRequest.EndGetRequestStream(callbackResult);

            // Create the post data
            byte[] byteArray = Encoding.UTF8.GetBytes(postUpdate);

            // Add the post data to the web request
            postStream.Write(byteArray, 0, byteArray.Length);
            postStream.Close();

            // Start the web request
            myRequest.BeginGetResponse(new AsyncCallback(GetResponsetStreamCallbackState), myRequest);
        }//GetRequestStreamCallbackState

        void GetResponsetStreamCallbackState(IAsyncResult callbackResult)
        {
            HttpWebRequest request = (HttpWebRequest)callbackResult.AsyncState;
            HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult);
            using (StreamReader httpWebStreamReader = new StreamReader(response.GetResponseStream()))
            {
                string result = httpWebStreamReader.ReadToEnd();
                Dispatcher.BeginInvoke(() => ParsingUpdateState(result));
            }
        }//GetResponsetStreamCallbackState

        void ParsingUpdateState(string result)
        {
            if (result != "")//successo errore
            {
                string[] ris = majorSplit(result);
                ris = minorSplit(ris[0]);//sono sicuro che è uno solo

                if (ris[0] == "ERRORE")
                    MessageBox.Show(ris[1]);//stampo l'errore
            }
            else //non sono avvenuti errori
            {
                if (forceGoBack)//mi ha disabilitato l'utente non può parlarli
                    NavigationService.GoBack();//forzo a tornare indietro
                else 
                { 
                    //refresh
                    RoutedEventArgs e = new RoutedEventArgs();
                    listUtente_Loaded(this, e);
                }   
            }
        }//ParsingUpdateState

        void GetRequestStreamCallbackChat(IAsyncResult callbackResult)
        {
            HttpWebRequest myRequest = (HttpWebRequest)callbackResult.AsyncState;
            // End the stream request operation
            Stream postStream = myRequest.EndGetRequestStream(callbackResult);

            // Create the post data
            string postData = "apikey=4nn!eSupp0rt&user1=" + IDuser+"&user2="+IDuser2;
            byte[] byteArray = Encoding.UTF8.GetBytes(postData);

            // Add the post data to the web request
            postStream.Write(byteArray, 0, byteArray.Length);
            postStream.Close();

            // Start the web request
            myRequest.BeginGetResponse(new AsyncCallback(GetResponsetStreamCallbackChat), myRequest);
        }//GetRequestStreamCallbackChat

        void GetResponsetStreamCallbackChat(IAsyncResult callbackResult)
        {
            HttpWebRequest request = (HttpWebRequest)callbackResult.AsyncState;
            HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult);
            using (StreamReader httpWebStreamReader = new StreamReader(response.GetResponseStream()))
            {
                string result = httpWebStreamReader.ReadToEnd();
                Dispatcher.BeginInvoke(() => ParsingChat(result));
            }
        }//GetResponsetStreamCallbackChat

        void ParsingChat(string result)
        {
            if (result != "")
            {
                listChat.Items.Clear();

                string[] ris = majorSplit(result);

                foreach (string mess in ris)//messaggio da stampare
                {
                    string[] dati = minorSplit(mess);

                    string mittente = dati[1];
                    string destinatario = dati[2];
                    string messaggio = dati[3];
                    string data = dati[4];

                    Border MessaggioChat = new Border();
                    if (int.Parse(mittente) == int.Parse(IDuser))//se il mittente sono io mi posiziono a destra
                        MessaggioChat.Style = MyTextStyle;
                    else //sono il destinatario e il messaggio va a sinistra
                        MessaggioChat.Style = YourTextStyle;

                    TextBlock tb = new TextBlock();
                    tb.Style = ChatTextStyle;
                    tb.Text = messaggio;//inserisco il messaggio preso dalla request

                    MessaggioChat.Child = tb;

                    listChat.Items.Add(MessaggioChat);
                }

                listChat.ScrollIntoView(listChat.Items.Last());
                listChat.Focus();
            }
            
 
        }//ParsingChat


        void Each_Tick(object sender, object e)
        {
            if (reload)
            { 
                //refresh
                RoutedEventArgs eve = new RoutedEventArgs();
                listChat_Loaded(this, eve);
            }
            
        }

        //ovveride del tasto back del telefono per fermare il timer
        protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
        {
            myDispatcherTimer.Stop();
            NavigationService.GoBack();
        }

        private void textBox_Tap(object sender, GestureEventArgs e)
        {
            reload = false;
        }

        private void textBox_GotFocus(object sender, RoutedEventArgs e)
        {
            reload = false;
        }

        private void textBox_LostFocus(object sender, RoutedEventArgs e)
        {
            reload = true;
        }

        private void listUtente_Loaded(object sender, RoutedEventArgs e)
        {
            //faccio request PHP al DB
            Uri myDBuri = new Uri("http://www.nearchat.altervista.org/datiUtente.php");
            HttpWebRequest datiRequest = (HttpWebRequest)HttpWebRequest.Create(myDBuri);
            datiRequest.Method = "POST";
            datiRequest.ContentType = "application/x-www-form-urlencoded";
            datiRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallbackDati), datiRequest);
        }

        private void listChat_Loaded(object sender, RoutedEventArgs e)
        {
            //faccio request PHP al DB
            Uri myDBuri = new Uri("http://www.nearchat.altervista.org/Chat.php");
            HttpWebRequest chatRequest = (HttpWebRequest)HttpWebRequest.Create(myDBuri);
            chatRequest.Method = "POST";
            chatRequest.ContentType = "application/x-www-form-urlencoded";
            chatRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallbackChat), chatRequest);
        }
    }
}